/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.service.impl;

import cn.hutool.core.util.StrUtil;
import com.yami.shop.bean.app.dto.ExpressQueryDto;
import com.yami.shop.bean.param.ExpressQueryParam;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.Json;
import com.yami.shop.config.Express100Config;
import com.yami.shop.service.Express100Service;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * 快递100 API服务实现类
 *
 * @author lgh
 */
@Service
@Slf4j
@AllArgsConstructor
public class Express100ServiceImpl implements Express100Service {

    private final Express100Config express100Config;
    private final RestTemplate restTemplate;

    @Override
    public ExpressQueryDto queryExpress(ExpressQueryParam param) {
        if (param == null || StrUtil.isBlank(param.getExpressCompanyCode()) || StrUtil.isBlank(param.getExpressNumber())) {
            throw new YamiShopBindException("快递公司编码和快递单号不能为空");
        }

        return queryExpress(param.getExpressCompanyCode(), param.getExpressNumber(), param.getPhone());
    }

    @Override
    public ExpressQueryDto queryExpress(String companyCode, String expressNo) {
        return queryExpress(companyCode, expressNo, null);
    }

    @Override
    public ExpressQueryDto queryExpress(String companyCode, String expressNo, String phone) {
        if (!isServiceAvailable()) {
            throw new YamiShopBindException("快递查询服务暂不可用");
        }

        try {
            // 构建请求参数
            Map<String, Object> requestBody = buildRequestBody(companyCode, expressNo, phone);

            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + express100Config.getApiKey());

            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);

            // 发送请求
            String url = express100Config.getBaseUrl() + express100Config.getQueryPath();
            ResponseEntity<String> response = restTemplate.exchange(
                url, HttpMethod.POST, requestEntity, String.class);

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                return parseResponse(response.getBody());
            } else {
                log.error("快递查询API返回异常状态码: {}", response.getStatusCode());
                throw new YamiShopBindException("快递查询服务返回异常");
            }

        } catch (Exception e) {
            log.error("快递查询失败: companyCode={}, expressNo={}, error={}",
                companyCode, expressNo, e.getMessage(), e);
            throw new YamiShopBindException("快递查询失败: " + e.getMessage());
        }
    }

    @Override
    public boolean isServiceAvailable() {
        return express100Config != null &&
               Boolean.TRUE.equals(express100Config.getEnabled()) &&
               StrUtil.isNotBlank(express100Config.getApiKey()) &&
               StrUtil.isNotBlank(express100Config.getBaseUrl());
    }

    /**
     * 构建请求体
     */
    private Map<String, Object> buildRequestBody(String companyCode, String expressNo, String phone) {
        Map<String, Object> requestBody = new HashMap<>();

        // 基础参数
        requestBody.put("com", companyCode);
        requestBody.put("num", expressNo);

        // 可选参数
        if (StrUtil.isNotBlank(phone)) {
            requestBody.put("phone", phone);
        }

        // 结果排序方式
        requestBody.put("resultv2", 1); // 默认降序排序

        // 是否返回签收状态
        requestBody.put("show", 1); // 默认返回签收状态

        // 是否返回快递公司信息
        requestBody.put("show_company", 1); // 默认返回快递公司信息

        return requestBody;
    }

    /**
     * 解析API响应
     */
    private ExpressQueryDto parseResponse(String responseBody) {
        try {
            Map<String, Object> responseMap = Json.parseObject(responseBody, Map.class);

            ExpressQueryDto result = new ExpressQueryDto();

            // 解析基础信息
            if (responseMap.containsKey("com")) {
                result.setExpressCompanyCode((String) responseMap.get("com"));
            }
            if (responseMap.containsKey("company")) {
                result.setExpressCompanyName((String) responseMap.get("company"));
            }
            if (responseMap.containsKey("nu")) {
                result.setExpressNumber((String) responseMap.get("nu"));
            }
            if (responseMap.containsKey("status")) {
                result.setExpressStatus((String) responseMap.get("status"));
            }
            if (responseMap.containsKey("state")) {
                String state = (String) responseMap.get("state");
                result.setIsSigned("3".equals(state)); // 3表示已签收
            }
            if (responseMap.containsKey("ischeck")) {
                result.setIsSigned("1".equals(responseMap.get("ischeck")));
            }

            // 解析快递轨迹
            if (responseMap.containsKey("data")) {
                List<Map<String, Object>> trackList = (List<Map<String, Object>>) responseMap.get("data");
                List<ExpressQueryDto.ExpressTrackDto> tracks = new ArrayList<>();

                for (Map<String, Object> trackMap : trackList) {
                    ExpressQueryDto.ExpressTrackDto track = new ExpressQueryDto.ExpressTrackDto();
                    track.setDescription((String) trackMap.get("context"));
                    track.setTime((String) trackMap.get("time"));
                    track.setLocation((String) trackMap.get("location"));
                    track.setStatus((String) trackMap.get("status"));
                    tracks.add(track);
                }

                result.setTracks(tracks);
            }

            // 解析快递公司信息
            if (responseMap.containsKey("companyInfo")) {
                Map<String, Object> companyInfo = (Map<String, Object>) responseMap.get("companyInfo");
                if (companyInfo != null) {
                    result.setExpressCompanyUrl((String) companyInfo.get("website"));
                    result.setExpressCompanyPhone((String) companyInfo.get("phone"));
                }
            }

            result.setQueryTime(new Date().toString());

            return result;

        } catch (Exception e) {
            log.error("解析快递查询响应失败: {}, responseBody={}", e.getMessage(), responseBody, e);
            throw new YamiShopBindException("解析快递查询结果失败");
        }
    }
}